package com.apexedu.biz.service.impl;

import com.apexedu.biz.entity.TSysUserTempEntity;
import com.apexedu.biz.entity.TUserResourceTemp;
import com.apexedu.biz.entity.TUserRoleTemp;
import com.apexedu.biz.entity.client.*;
import com.apexedu.framework.util.ConfigUtil;
import com.apexedu.framework.util.DBUtil;
import com.apexedu.framework.util.SeqFactory;
import com.apexedu.identity.entity.TSysMenu;
import com.apexedu.identity.entity.TSysRole;
import com.apexedu.identity.entity.TSysUser;
import com.apexedu.support.cache.CacheUtils;
import com.apexedu.sys.SysConstant;
import com.apexedu.sys.util.BusinessLogUtil;
import com.apexedu.util.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 报表解析器服务
 *
 * @author Yangjianliang
 */
@Service
@Transactional
public class AuthServiceImpl extends ResourceServiceImpl {
    private static final String portalKey = ConfigUtil.getString("portalCode");//门户接入号

    /**
     * 鉴权：检查当前用户有没有权限访问指定的资源
     *
     * @throws Exception
     */
    @Transactional(readOnly = true)
    public CommandResult checkRights(String clientAppId, String userLoginId, String srcId) throws Exception {

        clientAppId = checkClientAppId(clientAppId); // 断言接入号正确

        String cacheKey = "Auth" + userLoginId + clientAppId + srcId;
        ResourceEntity resourceEntity = (ResourceEntity) CacheUtils.get(cacheKey); // 缓存
        if (resourceEntity == null) {
            resourceEntity = new ResourceEntity();
            resourceEntity.setUserLoginId(userLoginId);
            resourceEntity.setSrcId(srcId);
            resourceEntity.setAppId(clientAppId);
            // 1. 鉴权
            String hql = "select e from TSysUser a, TSysUserRole b, TSysRole c, TSysRoleMenu d, TSysMenu e " +
                    "where a.userid=b.userid and b.roleid=c.roleid and c.roleid=d.roleid and d.menuid=e.menuid " +
                    "and a.userloginid=? and e.belongtoapp=? and e.bizcode=? and c.state=1 and e.state=1";
//            String menuPath = baseDao.findFieldValue(hql, userLoginId, clientAppId, srcId);
            TSysMenu sysMenu = baseDao.findBean(hql, userLoginId, clientAppId, srcId);
            if (sysMenu != null) {
                // 有权限
                resourceEntity.setHasRights(true);
                resourceEntity.setSrcRealUrl(sysMenu.getMenupath());
            }
            /*********如果为查询门户资源权限***********/
            if (portalKey.equals(clientAppId) && sysMenu == null) {
                String hql_portal = "select e from TSysUser a, TSysUserRole b, TSysRole c, TSysRoleMenu d, TSysMenu e " +
                        "where a.userid=b.userid and b.roleid=c.roleid and c.roleid=d.roleid and d.menuid=e.menuid " +
                        "and a.userloginid=?  and e.menuid=? and c.state=1 and e.state=1";
                String hql_query = "select t.qxzxid from S_FWZYK t where t.id = ? ";
                Object obj = DBUtil.queryFieldValue(hql_query, srcId);
                if (null != obj) {
                    String str = (String) obj;
                                    if (StringUtil.isNotBlank(str)) {
                                        sysMenu = baseDao.findBean(hql_portal, userLoginId, str);
                                        if (null != sysMenu) {
                                            // 有权限
                                            resourceEntity.setHasRights(true);
                        }
                    }
                }
            }
            CacheUtils.put(cacheKey, resourceEntity);
        }
        CommandResult result = new CommandResult();
        result.setResourceEntity(resourceEntity);
        return result;
    }

    /**
     * **
     * 角色同步，如果角色已经存在，则
     *
     * @param dataList
     * @param clientAppId
     * @return
     */
    public CommandResult uploadRolesBySTA(List<RoleEntity> dataList, String clientAppId) {
        clientAppId = checkClientAppId(clientAppId); // 断言接入号正确
        /*************过滤已经存在的角色，并执行更新操作****************/
        List<RoleEntity> roleEntities = getNewRoleEntity(dataList, clientAppId);
        /**************将过滤完的数据执行插入操作*******************/
        if (roleEntities != null && roleEntities.size() > 0) {
            List<TSysRole> sysRoles = new ArrayList<TSysRole>(roleEntities.size());
            for (int i = 0; i < roleEntities.size(); i++) {
                RoleEntity entity = roleEntities.get(i);
                TSysRole role = new TSysRole();
                role.setRoleid(SeqFactory.getNewSequenceAlone());
                role.setRolename(entity.getRoleName());
                role.setBelongtoapp(clientAppId);        //业务系统编号
                role.setBizcode(entity.getRoleId());   // 角色原编号
                role.setMemo(entity.getMemo());
                role.setState(entity.getRoleState() == null ? "1" : entity.getRoleState());
                sysRoles.add(role);
                // baseDao.save(role);
            }
            baseDao.saveAll(sysRoles);
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE, SysConstant.LOG_ACTION_SAVE, clientAppId);
        }
        CommandResult result = new CommandResult();
        return result;
    }

    public CommandResult deleteRolesBySTA(List<RoleEntity> dataList, String clientAppId) {

        clientAppId = checkClientAppId(clientAppId); // 断言接入号正确

        ArrayList<String> params = new ArrayList<String>(dataList.size());
        // 1.删除资源、角色关系
        StringBuilder hql = new StringBuilder("delete from t_sys_role_menu a where exists (select 1 from t_sys_role b where a.roleid=b.roleid and b.belongtoapp=? and ");
        params.add(clientAppId);
        hql.append(getRoleSqlWhereAndSetParams(dataList, params));
        hql.append(")");
        DBUtil.executeSQL(hql.toString(), params.toArray());
        BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE_MENU, SysConstant.LOG_ACTION_DEL, clientAppId);
        // 2.删除角色
        hql = new StringBuilder("delete from t_sys_role b where b.belongtoapp=? and ");
        params.clear();
        params.add(clientAppId);
        hql.append(getRoleSqlWhereAndSetParams(dataList, params));
        DBUtil.executeSQL(hql.toString(), params.toArray());
        BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE, SysConstant.LOG_ACTION_DEL, clientAppId);
        CommandResult result = new CommandResult();
        return result;
    }

    /**
     * 新增或更新用户数据
     *
     * @param roleUserEntities
     * @param clientAppId
     * @return
     */
    public CommandResult uploadUserBySTA(List<UserEntity> roleUserEntities, String clientAppId) {
        CommandResult result = new CommandResult();
        clientAppId = checkClientAppId(clientAppId);
        if (null != roleUserEntities && roleUserEntities.size() > 0) {
            List<TSysUserTempEntity> entityList = new ArrayList<TSysUserTempEntity>();
            // 1将数据保存到用户临时表中
            for (UserEntity roleUserEntity : roleUserEntities) {
                TSysUserTempEntity tempEntity = new TSysUserTempEntity();
                tempEntity.setWid(SeqFactory.getNewSequenceAlone());
                tempEntity.setState(roleUserEntity.getState());
                tempEntity.setUserloginid(roleUserEntity.getUserLoginId());
                tempEntity.setUsername(roleUserEntity.getUserName());
                tempEntity.setUsertype(roleUserEntity.getUserType());
                tempEntity.setUserpassword(roleUserEntity.getPassword());
                tempEntity.setClientappid(clientAppId);
                entityList.add(tempEntity);
            }
            baseDao.saveAll(entityList);

            //2、将所有用户表中存在的数据执行更新操作 (先执行更新操作，如先执行新增，则出现更新刚插入的数据)
            String hql2 = "update t_sys_user t set(t.username)=(select s.username from t_sys_user_temp s where s.userloginid=t.userloginid )" +
                    "where exists(select m.userloginid from  t_sys_user_temp m where m.userloginid=t.userloginid)";
            DBUtil.executeSQL(hql2);
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_USER, SysConstant.LOG_ACTION_UPDATE, clientAppId);
            //3、将所有正式表中不存在的临时表用户数据保存到正式表中
            String hql = "insert into t_sys_user (userid,state,usertype,userloginid,username,userdepart,userpwd)" +
                    "(select t.wid,t.state,t.usertype,t.userloginid,t.username,'000',t.userpassword from t_sys_user_temp t where not exists" +
                    "(select s.userloginid from t_sys_user s where s.userloginid=t.userloginid))";
            DBUtil.executeSQL(hql);//所有用户表不存在的数据插如到用户表中
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_USER, SysConstant.LOG_ACTION_SAVE, clientAppId);
            //4 ，删除临时表所有信息
            String hql_temp = "delete t_sys_user_temp t where t.clientappid = ? ";
            DBUtil.executeSQL(hql_temp, clientAppId);
            result.setHasError(false);
        }
        return result;
    }

    /**
     * 删除用户数据
     *
     * @param roleUserEntities
     * @param clientAppId
     * @return
     */
    public CommandResult deleteUserBySTA(List<UserEntity> roleUserEntities, String clientAppId) {
        clientAppId = checkClientAppId(clientAppId);
        CommandResult result = new CommandResult();
        if (null != roleUserEntities && roleUserEntities.size() > 0) {
            // 1，将删除信息保存在临时表中
            List<TSysUserTempEntity> entityList = new ArrayList<TSysUserTempEntity>();
            for (UserEntity tempEntity : roleUserEntities) {
                TSysUserTempEntity tSysUserTempEntity = new TSysUserTempEntity();
                tSysUserTempEntity.setWid(SeqFactory.getNewSequenceAlone());
                tSysUserTempEntity.setUserloginid(tempEntity.getUserLoginId());
                tSysUserTempEntity.setClientappid(clientAppId);
                entityList.add(tSysUserTempEntity);
            }
            baseDao.saveAll(entityList);
            //2, 如果删除用户中存在已授权用户，则返回客户端。
            String sql2 = "select * from  t_sys_user t where exists(select s.userloginid from t_sys_user_temp s where s.userloginid=t.userloginid ) " +
                    "and exists(select f.userid from t_sys_user_role f where f.userid=t.userid)";
            List<TSysUser> userList = DBUtil.queryAllBeanList(sql2, TSysUser.class);
            if (null != userList && userList.size() > 0) {
                List<UserEntity> list = new ArrayList<UserEntity>();
                for (TSysUser sysUser : userList) {
                    UserEntity roleUserEntity = new UserEntity();
                    roleUserEntity.setUserLoginId(sysUser.getUserloginid());
                    list.add(roleUserEntity);
                }
                result.setUserEntities(list);
                result.setHasError(true);
                result.setError("接受到" + roleUserEntities.size() + "条请求，其中" + userList.size() + "个用户已经授权，无法删除，这些用户的userloginid已经保存到 List<UserEntity>");
            }
            //3，删除系统未授权的用户
            String sql = "delete t_sys_user t where exists(select s.userloginid from t_sys_user_temp s where s.userloginid=t.userloginid ) " +
                    "and not exists(select f.userid from t_sys_user_role f where f.userid=t.userid)";
            DBUtil.executeSQL(sql);
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_USER, SysConstant.LOG_ACTION_DEL, clientAppId);
            //4 删除临时表数据
            String sql1 = "delete t_sys_user_temp t where t.clientappid = ? ";
            DBUtil.executeSQL(sql1, clientAppId);
        }

        return result;
    }

    private StringBuilder getRoleSqlWhereAndSetParams(List<RoleEntity> dataList, ArrayList<String> params) {
        StringBuilder hql = new StringBuilder("(");
        for (int i = 0; i < dataList.size(); i++) {
            RoleEntity entity = dataList.get(i);
            Assert.hasText(entity.getRoleId(), "角色编号不能为空");
            hql.append(" b.bizcode=? or");
            params.add(entity.getRoleId());
        }
        hql.delete(hql.length() - 2, hql.length());
        hql.append(")");
        return hql;
    }


    public CommandResult uploadRoleResourceMapBySTA(List<RoleResourceMapEntity> dataList, String clientAppId) {

        clientAppId = checkClientAppId(clientAppId); // 断言接入号正确

        CommandResult result = new CommandResult();
        if (dataList != null && dataList.size() > 0) {
            // 1.数据插入中转表
            List<TSysMapHelp> sysMapHelps = new ArrayList<TSysMapHelp>(dataList.size());
            for (int i = 0; i < dataList.size(); i++) {
                RoleResourceMapEntity entity = dataList.get(i);
                TSysMapHelp map = new TSysMapHelp();
                map.setId(SeqFactory.getNewSequenceAlone());
                map.setRoleid(entity.getRoleId());
                map.setRoleidBak(entity.getRoleId());
                map.setMenuOrUserId(entity.getSrcId());
                map.setMenuOrUserIdBak(entity.getSrcId());
                map.setBelongtoapp(clientAppId);
                map.setOptype("1"); // 1 表示 保存的数据是角色与资源关系
                sysMapHelps.add(map);
            }
            baseDao.saveAll(sysMapHelps);

            // 2.更新中转表的数据，编号转换成我们系统的规则编号
            String sql = "update T_SYS_MAP_HELP a set a.ROLEID=(select b.ROLEID from T_SYS_ROLE b where b.BELONGTOAPP=a.BELONGTOAPP and b.BIZCODE=a.ROLEID ), MENU_OR_USER_ID=(select c.MENUID from T_SYS_MENU c where c.BELONGTOAPP=a.BELONGTOAPP and c.BIZCODE=a.MENU_OR_USER_ID) where a.BELONGTOAPP=? and a.OPTYPE=1";
            DBUtil.executeSQL(sql, clientAppId);

            // 3.把规则数据插入正式表，删除中转表数据
            sql = "insert into T_SYS_ROLE_MENU(ID, ROLEID, MENUID) select ID, ROLEID, MENU_OR_USER_ID from T_SYS_MAP_HELP where BELONGTOAPP=? and OPTYPE=1 and ROLEID is not null and MENU_OR_USER_ID is not null"; // is not null 表示忽略了找不到匹配值的数据
            int size = DBUtil.executeSQL(sql, clientAppId);
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE_MENU, SysConstant.LOG_ACTION_SAVE, clientAppId);
            if (size < sysMapHelps.size()) {
                result.setHasError(true);
                sql = "select ROLEID_BAK as ROLEID , MENU_OR_USER_ID_BAK as MENU_OR_USER_ID from T_SYS_MAP_HELP where BELONGTOAPP=? and OPTYPE=2 and ROLEID is null or MENU_OR_USER_ID is null";
                List<TSysMapHelp> errList = DBUtil.queryAllBeanList(sql, TSysMapHelp.class, clientAppId);
                dataList.clear();
                for (TSysMapHelp map_ : errList) {
                    RoleResourceMapEntity entity = new RoleResourceMapEntity();
                    entity.setRoleId(map_.getRoleid());
                    entity.setSrcId(map_.getMenuOrUserId());
                    dataList.add(entity);
                }
                result.setRoleResourceMapEntities(dataList);
                result.setError("接收到 " + sysMapHelps.size() + "条关系记录，" + size + "条保存成功！不能执行的记录，已放回了 List<RoleResourceMapEntity> 中。这些记录对应的角色或资源在服务端不存在。");
            }

            sql = "delete from T_SYS_MAP_HELP where BELONGTOAPP=? and OPTYPE=1";
            DBUtil.executeSQL(sql, clientAppId);
        }
        return result;
    }

    // 用于解除指定资源和指定角色的关系
    public CommandResult deleteRoleResourceMapBySTA(List<RoleResourceMapEntity> dataList, String clientAppId) {

        clientAppId = checkClientAppId(clientAppId); // 断言接入号正确

        String hql = "delete from T_SYS_ROLE_MENU a where exists (select 1 from T_SYS_ROLE b, T_SYS_MENU c where a.roleid=b.roleid and a.menuid=c.menuid and c.belongtoapp=b.belongtoapp and b.belongtoapp=? and ( {0} ) )";
        StringBuilder where = new StringBuilder();
        ArrayList<String> params = new ArrayList<String>();
        params.add(clientAppId);
        for (int i = 0; i < dataList.size(); i++) {
            RoleResourceMapEntity entity = dataList.get(i);
            Assert.hasText(entity.getRoleId(), "角色编号不能为空");
            Assert.hasText(entity.getSrcId(), "资源编号不能为空");
            where.append("(b.bizcode = ? and c.bizcode = ?) or");
            params.add(entity.getRoleId());
            params.add(entity.getSrcId());
        }
        where.delete(where.length() - 2, where.length());

        hql = MessageFormat.format(hql, where.toString());
        DBUtil.executeSQL(hql, params.toArray());
        BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE_MENU, SysConstant.LOG_ACTION_DEL, clientAppId);
        CommandResult result = new CommandResult();
        return result;
    }

    public CommandResult uploadRoleUserMapBySTA(List<RoleUserMapEntity> dataList, String clientAppId) {

        clientAppId = checkClientAppId(clientAppId); // 断言接入号正确

        CommandResult result = new CommandResult();
        if (dataList != null && dataList.size() > 0) {
            // 1.数据插入中转表
            List<TSysMapHelp> sysMapHelps = new ArrayList<TSysMapHelp>(dataList.size());
            for (int i = 0; i < dataList.size(); i++) {
                RoleUserMapEntity entity = dataList.get(i);
                TSysMapHelp map = new TSysMapHelp();
                map.setId(SeqFactory.getNewSequenceAlone());
                map.setRoleid(entity.getRoleId());
                map.setRoleidBak(entity.getRoleId());
                map.setMenuOrUserId(entity.getUserLoginId());
                map.setMenuOrUserIdBak(entity.getUserLoginId());
                map.setBelongtoapp(clientAppId);
                map.setOptype("2"); // 2，表示角色与用户关系
                sysMapHelps.add(map);
            }
            baseDao.saveAll(sysMapHelps);

            // 2.更新中转表的数据，编号转换成我们系统的规则编号
            String sql = "update T_SYS_MAP_HELP a set a.ROLEID=(select b.ROLEID from T_SYS_ROLE b where b.BELONGTOAPP=a.BELONGTOAPP and b.BIZCODE=a.ROLEID ), MENU_OR_USER_ID=(select c.USERID from T_SYS_USER c where c.USERLOGINID=a.MENU_OR_USER_ID) where a.BELONGTOAPP=? and a.OPTYPE=2";
            DBUtil.executeSQL(sql, clientAppId);
            // 3.将中转表中，已经存在的用户角色关系删除。
            String delete_sql1 = " DELETE FROM T_SYS_MAP_HELP T WHERE EXISTS (SELECT S.ROLEID,S.USERID  FROM T_SYS_USER_ROLE S WHERE S.USERID=T.MENU_OR_USER_ID AND S.ROLEID=T.ROLEID) ";
            DBUtil.executeSQL(delete_sql1);
            // 4.把规则数据插入正式表，删除中转表数据
            sql = "insert into T_SYS_USER_ROLE(ID, ROLEID, USERID) select ID, ROLEID, MENU_OR_USER_ID from T_SYS_MAP_HELP where BELONGTOAPP=? and OPTYPE=2 and ROLEID is not null and MENU_OR_USER_ID is not null"; // is not null 表示忽略了找不到匹配值的数据
            int size = DBUtil.executeSQL(sql, clientAppId);
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_USER_ROEL, SysConstant.LOG_ACTION_SAVE, clientAppId);
            if (size < sysMapHelps.size()) {
                sql = "select ROLEID_BAK as ROLEID , MENU_OR_USER_ID_BAK as MENU_OR_USER_ID from T_SYS_MAP_HELP where BELONGTOAPP=? and OPTYPE=2 and ROLEID is null or MENU_OR_USER_ID is null";
                List<TSysMapHelp> errList = DBUtil.queryAllBeanList(sql, TSysMapHelp.class, clientAppId);
                dataList.clear();
                if (null != errList && errList.size() > 0) {
                    result.setHasError(true);
                    for (TSysMapHelp map_ : errList) {
                        RoleUserMapEntity entity = new RoleUserMapEntity();
                        entity.setRoleId(map_.getRoleid());
                        entity.setUserLoginId(map_.getMenuOrUserId());
                        dataList.add(entity);
                    }
                    result.setRoleUserMapEntities(dataList);
                    result.setError("接收到 " + sysMapHelps.size() + "条关系记录，" + size + "条保存成功！不能执行的记录，已放回了 List<RoleUserMapEntity> 中。这些记录对应的角色或者用户在服务端不存在。");
                }
            }
            sql = "delete from T_SYS_MAP_HELP where BELONGTOAPP=? and OPTYPE=2";
            DBUtil.executeSQL(sql, clientAppId);
        }
        return result;
    }

    public CommandResult deleteRoleUserMapBySTA(List<RoleUserMapEntity> dataList, String clientAppId) {
        clientAppId = checkClientAppId(clientAppId); // 断言接入号正确
        String hql = "delete from T_SYS_USER_ROLE a where exists (select 1 from T_SYS_ROLE b, T_SYS_USER c where a.roleid=b.roleid and a.userid=c.userid and b.belongtoapp=? and ( {0} ) )";
        StringBuilder where = new StringBuilder();
        ArrayList<String> params = new ArrayList<String>();
        params.add(clientAppId);
        for (int i = 0; i < dataList.size(); i++) {
            RoleUserMapEntity entity = dataList.get(i);
            Assert.hasText(entity.getRoleId(), "角色编号不能为空");
            Assert.hasText(entity.getUserLoginId(), "用户登录账户不能为空");
            where.append("(b.bizcode = ? and c.userloginid = ?) or");
            params.add(entity.getRoleId());
            params.add(entity.getUserLoginId());
        }
        where.delete(where.length() - 2, where.length());

        hql = MessageFormat.format(hql, where.toString());
        DBUtil.executeSQL(hql, params.toArray());
        BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_USER_ROEL, SysConstant.LOG_ACTION_DEL, clientAppId);
        CommandResult result = new CommandResult();
        return result;
    }

    public CommandResult getAccessSystems(String clientAppId) {

        CommandResult result = new CommandResult();

        String cacheKey = "AccessSystemsList";
        List<AccessAppRegInfo> accessAppRegs = (List<AccessAppRegInfo>) CacheUtils.get(cacheKey); // 缓存
        if (accessAppRegs == null) {
            String sql = "select appid, appname, SYNC_DIRECTION as syncDirection from t_access_app_reg where state=1";
            accessAppRegs = DBUtil.queryAllBeanList(sql, AccessAppRegInfo.class);
            CacheUtils.put(cacheKey, accessAppRegs, 60 * 3); // 缓存3分钟
        }
        result.setAccessAppRegInfos(accessAppRegs);
        return result;
    }

    /**
     * 同步角色(带删除)
     *
     * @param roleEntities
     * @param clientAppId
     * @return
     */
    public CommandResult updateOrDeleteRole(List<RoleEntity> roleEntities, String clientAppId) {
        clientAppId = checkClientAppId(clientAppId); // 断言接入号正确
        CommandResult result = new CommandResult();
        /**第一步，将数据保存到临时表中。*/
        List<TUserRoleTemp> list = new ArrayList<TUserRoleTemp>();
        if (null != roleEntities && roleEntities.size() > 0) {
            for (RoleEntity roleEntity : roleEntities) {
                TUserRoleTemp tUserRoleTemp = new TUserRoleTemp();
                tUserRoleTemp.setWid(SeqFactory.getNewSequenceAlone());
                tUserRoleTemp.setBelongtoapp(clientAppId);
                tUserRoleTemp.setRoleid(roleEntity.getRoleId());
                tUserRoleTemp.setMemo(roleEntity.getMemo());
                tUserRoleTemp.setRolename(roleEntity.getRoleName());
                tUserRoleTemp.setState(roleEntity.getRoleState() == null ? "1" : roleEntity.getRoleState());
                list.add(tUserRoleTemp);
            }
            baseDao.saveAll(list);
            /**第二步，先将临时表和正式表中都存在的数据执行更新操作*/
            String hql_update = "update t_sys_role t set(t.rolename,t.state,t.memo)=(select s.rolename,s.state,s.memo from t_user_role_temp s where s.roleid=t.bizcode)" +
                    "where exists(select m.roleid from t_user_role_temp m where m.roleid=t.bizcode) and t.belongtoapp=?";
            int updateNumber = DBUtil.executeSQL(hql_update, clientAppId);
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE, SysConstant.LOG_ACTION_UPDATE, clientAppId);
            /**第三步，将正式表中不存在的数据插入到正式表中。*/
            String hql_insert = "insert into t_sys_role(roleid,rolename,state,memo,belongtoapp,bizcode)" +
                    "(select s.wid,s.rolename,s.state,s.memo,s.belongtoapp,s.roleid from t_user_role_temp s where not " +
                    "exists(select t.bizcode from t_sys_role t where t.bizcode=s.roleid))";
            int insertNumber = DBUtil.executeOneoffSQL(hql_insert);
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE, SysConstant.LOG_ACTION_SAVE, clientAppId);
            /**第四步，将正式表中存在，临时表中不存在的数据对应的角色资源关系先删除。*/
            String hql_delete_roleResourceMap = "delete from T_SYS_ROLE_MENU t where exists(select s.roleid from t_sys_role s" +
                    " where s.roleid = t.roleid and not exists(select m.roleid from t_user_role_temp m where m.roleid=s.bizcode) and s.belongtoapp = ? )";
           DBUtil.executeSQL(hql_delete_roleResourceMap, clientAppId);
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE_MENU, SysConstant.LOG_ACTION_DEL, clientAppId);
            /**第五步，删除角色表中多余数据实现和客户端同步*/
            String hql_delete_role = "delete from t_sys_role t where not exists(select m.roleid from t_user_role_temp m where m.roleid =t.bizcode" +
                    ") and t.belongtoapp= ? ";
            int RoleDeleteNumber = DBUtil.executeSQL(hql_delete_role, clientAppId);
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE, SysConstant.LOG_ACTION_DEL, clientAppId);
            /**第六步，删除临时表数据*/
            String hql = "delete from t_user_role_temp t where t.belongtoapp = ? ";
           DBUtil.executeSQL(hql, clientAppId);
            result.setError("成功更新了：" + updateNumber + "条数据；新增了：" + insertNumber + "条数据；删除了：" + RoleDeleteNumber + "条数据。");//将同步结果返回客户端。
        }
        return result;
    }

    /**
     * 同步更新角色资源关系（带删除）
     *
     * @param roleResourceMapEntities
     * @param clientAppId
     * @return
     */
    public CommandResult updateOrDeleteResourceRoleMap(List<RoleResourceMapEntity> roleResourceMapEntities, String clientAppId) {
        CommandResult result = new CommandResult();
        clientAppId = checkClientAppId(clientAppId); // 断言接入号正确
        if (null != roleResourceMapEntities && roleResourceMapEntities.size() > 0) {
            /**第一步，将数据保存到临时表中*/
            List<TSysMapHelp> sysMapHelps = new ArrayList<TSysMapHelp>();
            for (RoleResourceMapEntity roleResourceMapEntity : roleResourceMapEntities) {
                TSysMapHelp map = new TSysMapHelp();
                map.setId(SeqFactory.getNewSequenceAlone());
                map.setRoleid(roleResourceMapEntity.getRoleId());
                map.setRoleidBak(roleResourceMapEntity.getRoleId());
                map.setMenuOrUserId(roleResourceMapEntity.getSrcId());
                map.setMenuOrUserIdBak(roleResourceMapEntity.getSrcId());
                map.setBelongtoapp(clientAppId);
                map.setOptype("1"); // 1 表示 保存的数据是角色与资源关系
                sysMapHelps.add(map);
            }
            baseDao.saveAll(sysMapHelps);
            /**第二步，将正式表中不存在的有效数据插入到正式表中*/
            String hql_insert = "insert into T_SYS_ROLE_MENU (id,roleid,menuid)(select t.id,h.roleid,h1.menuid from t_sys_map_help t left join(" +
                    "select s.roleid ,s.bizcode,s.belongtoapp from t_sys_role s group by s.roleid ,s.bizcode,s.belongtoapp ) h on h.bizcode=t.roleid " +
                    "left join(select d.menuid,d.bizcode,d.belongtoapp from t_sys_menu d group by d.menuid,d.bizcode,d.belongtoapp)h1 on h1.bizcode=t.menu_or_user_id " +
                    "where t.roleid=h.bizcode and h1.bizcode=t.menu_or_user_id and h1.menuid is not null and h.roleid is not null " +
                    "and not exists(select f.roleid from t_sys_role_menu f where f.roleid=h.roleid) " +
                    "or not exists(select m.menuid from t_sys_role_menu m where  m.menuid=h1.menuid) and h.belongtoapp=? and h1.belongtoapp=? and t.optype=1" +
                    " and t.belongtoapp= ? )";
            List<Object> params = new LinkedList<Object>();
            params.add(clientAppId);
            params.add(clientAppId);
            params.add(clientAppId);
            int s = DBUtil.executeSQL(hql_insert, params.toArray());
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE_MENU, SysConstant.LOG_ACTION_SAVE, clientAppId);
            /**第三步，将临时表中不存在的数据删除*/
            String hql_delete = "delete from t_sys_role_menu l where exists(select t.id from t_sys_role_menu t left join(" +
                    " select s.roleid ,s.bizcode,s.belongtoapp from t_sys_role s where s.belongtoapp= ? group by s.roleid ,s.bizcode,s.belongtoapp" +
                    ") h on h.roleid=t.roleid left join(select d.menuid,d.bizcode,d.belongtoapp from t_sys_menu d where d.belongtoapp =? group by d.menuid,d.bizcode,d.belongtoapp" +
                    ")h1 on h1.menuid=t.menuid where t.roleid=h.roleid and h1.menuid=t.menuid and t.menuid is not null and t.roleid is not null" +
                    " and not exists(select f.roleid from t_sys_map_help f and f.belongtoapp=? where f.roleid=h.roleid)" +
                    "and not exists(select m.menu_or_user_id from t_sys_map_help m and m.belongtoapp=? where  m.menu_or_user_id=h1.menuid) and l.id=t.id " +
                    ") ";
            params.add(clientAppId);
            int t = DBUtil.executeSQL(hql_delete, params.toArray());
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_ROLE_MENU, SysConstant.LOG_ACTION_DEL, clientAppId);
            /**第四步，删除临时表数据*/
            String hql = "delete from t_sys_map_help t where t.belongtoapp=?";
            DBUtil.executeSQL(hql, clientAppId);
            result.setError("更新了：" + s + "条数据，删除了：" + t + "条数据");
        }
        return result;
    }

    /**
     * 同步资源（带删除服务端无效数据）
     *
     * @param list
     * @param clientAppId
     * @return
     */
    public CommandResult updateOrDeleteResource(List<ResourceEntity> list, String clientAppId) {
        CommandResult result = new CommandResult();
        clientAppId = checkClientAppId(clientAppId); // 断言接入号正确
        if (null != list && list.size() > 0) {
            /**第一步，将数据保存到临时表中*/
            List<TUserResourceTemp> userResourceTempList = new ArrayList<TUserResourceTemp>();
            for (ResourceEntity resourceEntity : list) {
                TUserResourceTemp tUserResourceTemp = new TUserResourceTemp();
                tUserResourceTemp.setWid(SeqFactory.getNewSequenceAlone());//编号
                tUserResourceTemp.setAppid(clientAppId);//系统接入号
                tUserResourceTemp.setSrcid(resourceEntity.getSrcId());//资源编号
                tUserResourceTemp.setSrctitle(resourceEntity.getSrcTitle());//资源名称
                tUserResourceTemp.setSrctype(resourceEntity.getSrcType());//资源类型
                tUserResourceTemp.setSrcurl(resourceEntity.getSrcRealUrl());//资源内容
                userResourceTempList.add(tUserResourceTemp);
            }
            baseDao.saveAll(userResourceTempList);
            /**第二步，将已经存在的数据执行更新操作*/
            String hql_update = "update t_sys_menu t set( t.menuname,t.menupath,t.upmenuid,t.srctype,t.upbizcode)=" +
                    "(select m.srctitle,m.srcurl,nvl((select s.menuid from t_sys_menu s where s.upmenuid=m.srcupid),'000')as upmenuid,m.srctype,m.srcupid from t_user_resource_temp m " +
                    "where t.bizcode =m.srcid and t.belongtoapp =m.appid) where exists(select l.srcid from t_user_resource_temp l where l.srcid=t.bizcode and t.belongtoapp =l.appid)  ";
            int updateNumber = DBUtil.executeSQL(hql_update);
            BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_MENU, SysConstant.LOG_ACTION_UPDATE, clientAppId);
            /**第三步，将新增加数据插入到正式表中*/
            //a.将所有需要插入的数据查出来。
            String sql_select = "select * from t_user_resource_temp t where not exists(select s.bizcode from t_sys_menu s where s.bizcode=t.srcid )" +
                    " and t.appid = ? ";
            List<TUserResourceTemp> resourceTempList = DBUtil.queryAllBeanList(sql_select, TUserResourceTemp.class, clientAppId);
            int saveNumber = 0;
            //b.将资源编号转为权限中心统一编号。
            if (null != resourceTempList && resourceTempList.size() > 0) {
                List<TSysMenu> sysMenuList = new ArrayList<TSysMenu>();
                for (TUserResourceTemp temp : resourceTempList) {
                    TSysMenu tSysMenu = new TSysMenu();
                    tSysMenu.setSrctype(temp.getSrctype());//资源类型
                    tSysMenu.setOrdernum(100);
                    tSysMenu.setState("1");
                    tSysMenu.setIsshare("0");
                    tSysMenu.setBelongtoapp(clientAppId);//接入系统编号
                    tSysMenu.setMenuname(temp.getSrctitle());//名称
                    tSysMenu.setBizcode(temp.getSrcid());//原编号
                    tSysMenu.setUpbizcode(temp.getSrcupid());//原上级编号
                    tSysMenu.setMenupath(temp.getSrcurl());//地址
                    String upMenuid = getUpMemuId(sysMenuList, clientAppId, temp.getSrcupid());
                    tSysMenu.setUpmenuid(upMenuid);//父编号
                    try {
                        String MenuId = ResourceServiceImpl.getNewMenuIdByParentMenuId(sysMenuList, upMenuid);
                        tSysMenu.setMenuid(MenuId);//节点编号
                        tSysMenu.setDepth(Short.decode(String.valueOf(MenuId.length() / 3)));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    sysMenuList.add(tSysMenu);
                }
                baseDao.saveAll(sysMenuList);
                BusinessLogUtil.log(clientAppId, SysConstant.CZDX_T_SYS_MENU, SysConstant.LOG_ACTION_SAVE, clientAppId);
                saveNumber = sysMenuList.size();
            }
            /**第四步，权限中心多余的数据执行删除*/
            //a.先删除资源角色关系
            String hql_Menu = "delete from T_SYS_ROLE_MENU t where exists(select s.menuid from t_sys_menu s where s.menuid=t.menuid and not exists" +
                    "(select m.srcid from t_user_resource_temp m where m.secid= s.bizcode and m.appid = ? ) and s.belongtoapp = ? )";
            List<Object> params = new LinkedList<Object>();
            params.add(clientAppId);
            params.add(clientAppId);
            DBUtil.executeSQL(hql_Menu, params.toArray());
            //b.删除资源
            String hql_delete_menu = "delete from t_sys_menu t where not exists(select m.srcid from t_user_resource_temp m where m.secid= t.bizcode and m.appid= ?) " +
                    " and t.belongtoapp = ? ";
            int deleteNumber = DBUtil.executeSQL(hql_delete_menu, params.toArray());
            result.setError("成功更新：" + updateNumber + "条数据，新增：" + saveNumber + "条数据,删除：" + deleteNumber + "条数据。");
            /**第五步，删除临时表数据*/
            String hql = "delete from t_user_resource_temp t where t.appis=?";
            DBUtil.executeSQL(hql, clientAppId);
        }
        return result;
    }

    public String getUpMemuId(List<TSysMenu> list, String clientAppId, String upSrcId) {
        String upMenuid = "";
        List<Object> params = new LinkedList<Object>();
        params.add(upSrcId);
        params.add(clientAppId);
        TSysMenu tSysMenu = DBUtil.queryBean("select * from t_sys_menu t where t.bizcode = ? and t.belongtoapp = ? ", TSysMenu.class, params.toArray());
        if (null != tSysMenu) {
            upMenuid = tSysMenu.getMenuid();
        } else if (null != list && list.size() > 0) {
            for (TSysMenu tSysMenu1 : list) {
                if (tSysMenu1.getBizcode().equals(upSrcId)) {
                    upMenuid = tSysMenu1.getMenuid();
                }
            }
        } else {
            upMenuid = "000";
        }
        return upMenuid;
    }

    /**
     * 找出已经存在的角色，并更新已经存在的角色信息
     *
     * @param list
     * @param clientAppId
     * @return
     */
    public List<RoleEntity> getNewRoleEntity(List<RoleEntity> list, String clientAppId) {
        if (null != list && list.size() > 0) {
            List<TSysRole> sysRoles = getRole(list, clientAppId);
            List<RoleEntity> list1 = new LinkedList<RoleEntity>();
            if (null != sysRoles && sysRoles.size() > 0) {
                /********开始过滤角色，并更新存在的角色********/
                for (int i = 0; i < list.size(); i++) {
                    RoleEntity roleEntity = list.get(i);
                    boolean msg = true;
                    if (StringUtil.isNotBlank(roleEntity.getRoleId())) {
                        for (TSysRole tSysRole : sysRoles) {
                            if (roleEntity.getRoleId().equals(tSysRole.getBizcode())) {//原始编号相同
                                msg = false;
                                tSysRole.setRolename(roleEntity.getRoleName());
                                tSysRole.setState(roleEntity.getRoleState() == null ? "1" : roleEntity.getRoleState());
                                tSysRole.setMemo(roleEntity.getMemo());
                                baseDao.update(tSysRole);
                                break;
                            }
                        }
                        if (msg) {
                            list1.add(roleEntity);
                        }
                    }
                }
            }
            return list;
        }
        return list;
    }

    /**
     * 查询出已经存在的角色
     *
     * @param list
     * @param clientAppId
     * @return
     */
    public List<TSysRole> getRole(List<RoleEntity> list, String clientAppId) {
        if (null != list && list.size() > 0 && StringUtil.isNotBlank(clientAppId)) {
            StringBuilder hql = new StringBuilder("select * from t_sys_role t where t.belongtoapp = ? and(");
            List<Object> params = new LinkedList<Object>();
            params.add(clientAppId);
            for (int i=0;i<list.size();i++) {
                RoleEntity roleEntity=list.get(i);
                if (0==i) {
                    hql.append(" t.bizcode = ? ");
                    params.add(roleEntity.getRoleId());
                }else{
                    hql.append(" or t.bizcode = ? ");
                    params.add(roleEntity.getRoleId());
                }
            }
            hql.append(")");
            System.out.print(hql.toString());
            List<TSysRole> sysRoles = DBUtil.queryAllBeanList(hql.toString(), TSysRole.class, params.toArray());//查询已经存在的角色
            return sysRoles;
        }
        return null;
    }
}

